package com.javatiaocao.myblog.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.javatiaocao.myblog.constant.CodeType;
import com.javatiaocao.myblog.mapper.ArticleMapper;
import com.javatiaocao.myblog.mapper.StatisticMapper;
import com.javatiaocao.myblog.mapper.UserMapper;
import com.javatiaocao.myblog.mapper.VisitorMapper;
import com.javatiaocao.myblog.model.Article;
import com.javatiaocao.myblog.model.ArticleLikesRecord;
import com.javatiaocao.myblog.model.User;
import com.javatiaocao.myblog.model.Visitor;
import com.javatiaocao.myblog.service.ArticleService;
import com.javatiaocao.myblog.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    VisitorMapper visitorMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StatisticMapper statisticMapper;


    /**
     * 获取文章列表分页
     */
    @Override
    public DataMap selectArticleWithPage(int rows, int pageNum) {
        //开启分页插件
        PageHelper.startPage(pageNum, rows);

        //返回数据处理
        JSONObject returnJson = new JSONObject();//最终返回data
        JSONObject pageInfo = new JSONObject();//存储页面信息
        JSONArray returnJsonArray = new JSONArray();//文章json数列

        //查询文章
        List<Article> list = articleMapper.selectArticleWithPage();
        PageInfo<Article> pageInfoHelper = new PageInfo<Article>(list);

        //判断是否为空
        if (list.isEmpty()) {
            return DataMap.fail(CodeType.ARTICLE_NOT_EXIST);
        }

        for (Article article : list) {
            JSONObject jsonObject = new JSONObject();

            jsonObject.put("id", article.getId());
            jsonObject.put("articleId", article.getArticleId());
            jsonObject.put("articleTitle", article.getArticleTitle());
            jsonObject.put("publishDate", article.getPublishDate());
            jsonObject.put("articleCategories", article.getArticleCategories());
            jsonObject.put("visitorNum", visitorMapper.getVisitorNum("article/" + article.getArticleId()).getVisitorNum());
            jsonObject.put("originalAuthor", article.getOriginalAuthor());
            returnJsonArray.add(jsonObject);
        }

        //页面数据
        pageInfo.put("pageSize", pageInfoHelper.getPageSize());
        pageInfo.put("pageNum", pageInfoHelper.getPageNum());
        pageInfo.put("pages", pageInfoHelper.getPages());
        pageInfo.put("total", pageInfoHelper.getTotal());
        pageInfo.put("isFirstPage", pageInfoHelper.isIsFirstPage());
        pageInfo.put("isLastPage", pageInfoHelper.isIsLastPage());

        //添加返回值
        returnJson.put("pageInfo", pageInfo);
        returnJson.put("result", returnJsonArray);

        return DataMap.success().setData(returnJson);
    }

    /**
     * 首页分页查询
     */

    @Override
    public DataMap selectMyArticleWithPage(int rows, int pageNum) {
        //开启分页插件
        PageHelper.startPage(pageNum, rows);

        //返回数据处理
        JSONObject pageInfo = new JSONObject();//存储页面信息


        //查询文章
        List<Article> list = articleMapper.selectArticleWithPage();
        PageInfo<Article> pageInfoHelper = new PageInfo<Article>(list);


        //对象需要返回数据'thisArticleUrl',articleTitle,articleType,
        //publishDate,originalAuthor,articleCategories,articleTabloid,articleTags[],
        List<Map> newArticleList = new ArrayList<>();
        for (Article article : list) {
            HashMap<Object, Object> articleHashMap = new HashMap<>();
            articleHashMap.put("thisArticleUrl", article.getArticleUrl());
            articleHashMap.put("articleTitle", article.getArticleTitle());
            articleHashMap.put("publishDate", article.getPublishDate());
            articleHashMap.put("articleType", article.getArticleType());
            articleHashMap.put("originalAuthor", article.getOriginalAuthor());
            articleHashMap.put("articleCategories", article.getArticleCategories());
            articleHashMap.put("articleTabloid", article.getArticleTabloid());
            articleHashMap.put("articleTags", article.getArticleTags().split(","));
            newArticleList.add(articleHashMap);
        }
        JSONArray returnJsonArray = JSONArray.parseArray(JSON.toJSONString(newArticleList));

        //页面数据
        pageInfo.put("pageSize", pageInfoHelper.getPageSize());
        pageInfo.put("pageNum", pageInfoHelper.getPageNum());
        pageInfo.put("pages", pageInfoHelper.getPages());
        pageInfo.put("total", pageInfoHelper.getTotal());


        //添加返回值
        returnJsonArray.add(pageInfo);

        return DataMap.success().setData(returnJsonArray);
    }


    /**
     * 删除文章
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DataMap deleteArticle(Integer id) {
        //查询数据库中是否存在这个文章
        Article article = articleMapper.getArticleByid(id);
        if (article == null) {
            return DataMap.fail(CodeType.ARTICLE_NOT_EXIST);
        }
        //上下文id修改
        articleMapper.updateLastNextId("lastArticleId", article.getLastArticleId(), article.getNextArticleId());
        articleMapper.updateLastNextId("nextArticleId", article.getLastArticleId(), article.getNextArticleId());
        //删除本文
        articleMapper.deleteArticleById(id);
        //其他表记录
        //TODO


        return DataMap.success();
    }


    /**
     * 发表文章
     * @param article
     * @return
     */
    @Override
    public DataMap publishArticle(Article article) {
        //设置发布时间
        TimeUtil timeUtil = new TimeUtil();
        article.setArticleId(timeUtil.getLongTime());
        article.setPublishDate(timeUtil.getFormatDateForThree());
        article.setUpdateDate(timeUtil.getFormatDateForThree());
        if (StringUtil.BLANK.equals(article.getOriginalAuthor())) {
            article.setOriginalAuthor(article.getAuthor());
        }
        if (article.getArticleUrl().equals(StringUtil.BLANK)) {
            //url
            article.setArticleUrl("http://localhost:9007/article/" + timeUtil.getLongTime());
        }

        //创建时间戳
        BuildArticleTabloidUtil buildArticleTabloidUtil = new BuildArticleTabloidUtil();
        article.setArticleTabloid(buildArticleTabloidUtil.buildArticleTabloid(article.getArticleContent()));

        String articleVisitor = "article/" + article.getArticleId();
        articleMapper.publishArticle(article);
        visitorMapper.articleVisitor(articleVisitor);
        //数据封装
        JSONObject returnObject = new JSONObject();
        returnObject.put("articleUrl", article.getArticleUrl());
        returnObject.put("author", article.getAuthor());
        returnObject.put("updateDate", article.getUpdateDate());
        returnObject.put("articleTitle", article.getArticleTitle());
        return DataMap.success(CodeType.SUCCESS_STATUS).setData(returnObject);
    }


    /**
     * 更新文章
     **/
    @Override
    public DataMap updateArticle(Article article) {
        if (article == null) {
            return DataMap.fail(CodeType.ARTICLE_NOT_EXIST);
        }

        //设置更新时间
        TimeUtil timeUtil = new TimeUtil();
        article.setUpdateDate(timeUtil.getFormatDateForThree());

        //以下数据会改动：作者，标题，标签，文章内容，文章类型，分类，等级，文章作者，原文链接，摘要
        articleMapper.updateArticleById(article);

        //数据封装
        JSONObject returnObject = new JSONObject();
        returnObject.put("articleUrl", article.getArticleUrl());
        returnObject.put("author", article.getAuthor());
        returnObject.put("updateDate", article.getUpdateDate());
        returnObject.put("articleTitle", article.getArticleTitle());
        return DataMap.success(CodeType.SUCCESS_STATUS).setData(returnObject);
    }

    /**
     * 草稿
     **/
    @Override
    public DataMap getDraftArticle(Integer id) {
        Article draftArticle = articleMapper.getArticleByid(id);
        JSONObject returnArticle = new JSONObject();

        //文章数据回传
        returnArticle.put("articleTitle", draftArticle.getArticleTitle());
        returnArticle.put("articleContent", draftArticle.getArticleContent());
        returnArticle.put("articleType", draftArticle.getArticleType());
        returnArticle.put("articleGrade", 20);
        returnArticle.put("originalAuthor", draftArticle.getOriginalAuthor());
        returnArticle.put("articleUrl", draftArticle.getArticleUrl());
        returnArticle.put("articleCategories", draftArticle.getArticleCategories());
        String[] tagList = draftArticle.getArticleTags().split(",");
        List<String> list = Arrays.asList(tagList);
        ArrayList<String> newTagsList = new ArrayList<>(list);
        newTagsList.remove(tagList.length - 1);

        returnArticle.put("articleTags", newTagsList);
        returnArticle.put("id", draftArticle.getArticleId());

        return DataMap.success().setData(returnArticle);
    }


    /**
     * 获取文章点赞量
     * @param phone
     * @param rows
     * @param pageNum
     * @return
     */
    @Override
    public DataMap getArticleThumbsUp(String phone, int rows, int pageNum) {
        PageHelper.startPage(pageNum, rows);
        //返回数据处理
        JSONObject returnResult = new JSONObject();

        //查询账户拥有文章
        List<Article> articleList = articleMapper.selectArticleByPhone(phone);
        PageInfo<Article> pageInfo = new PageInfo<>(articleList);

        //写入文章
        JSONArray articleArray = new JSONArray();
        int msgIsNotReadNum = 0;
        for (Article article : articleList) {
            List<ArticleLikesRecord> articleLikesRecordList = articleMapper.selectArticleByAId(article.getArticleId());
            for (ArticleLikesRecord articleLikesRecord : articleLikesRecordList) {
                JSONObject articleJsonObject = new JSONObject();
                articleJsonObject.put("articleId", article.getArticleId());
                articleJsonObject.put("articleTitle", article.getArticleTitle());
                articleJsonObject.put("likeDate", articleLikesRecord.getLikeDate());
                User user = userMapper.selectUserById(articleLikesRecord.getLikerId());
                articleJsonObject.put("praisePeople", user.getUsername());
                articleJsonObject.put("id", user.getId());
                articleJsonObject.put("isRead", articleLikesRecord.getIsRead());
                articleArray.add(articleJsonObject);//'result'
                if (articleLikesRecord.getIsRead() == 1) {
                    msgIsNotReadNum += 1;
                }
            }
        }

        //页面数据
        JSONObject pageObject = new JSONObject();
        pageObject.put("pageSize", pageInfo.getPageSize());
        pageObject.put("pageNum", pageInfo.getPageNum());
        pageObject.put("pages", pageInfo.getPages());
        pageObject.put("total", pageInfo.getTotal());

        //数据封装
        returnResult.put("result", articleArray);
        returnResult.put("msgIsNotReadNum", msgIsNotReadNum);
        returnResult.put("pageInfo", pageObject);


        return DataMap.success().setData(returnResult);
    }


    /**
     * 全部已读
     * @param phone
     * @return
     */
    @Override
    public DataMap readAllThumbsUp(String phone) {
        List<Article> articleList = articleMapper.selectArticleByPhone(phone);
        for (Article article : articleList) {
            articleMapper.readAllById(article.getArticleId());
        }
        return DataMap.success();
    }


    /**
     * 首页显示文章
     * @param articleId
     * @return
     */
    @Override
    public Map<String, String> findArticleTitleByArticleId(long articleId) {
        Article articleInfo = articleMapper.getArticleDetailByArticleId(articleId);
        HashMap<String, String> articleMap = new HashMap<>();
        if (articleInfo != null) {
            articleMap.put("publishDate", articleInfo.getPublishDate());
            articleMap.put("articleTitle", articleInfo.getArticleTitle());
            articleMap.put("articleType", articleInfo.getArticleType());
            articleMap.put("originalAuthor", articleInfo.getOriginalAuthor());
            articleMap.put("articleCategories", articleInfo.getArticleCategories());
            articleMap.put("articleContent", articleInfo.getArticleContent());
            articleMap.put("articleUrl", articleInfo.getArticleUrl());
            articleMap.put("articleTags", articleInfo.getArticleTags());
            articleMap.put("articleId", String.valueOf(articleInfo.getArticleId()));
            articleMap.put("articleTabloid", articleInfo.getArticleTabloid());
            return articleMap;
        }
        return null;
    }



    /**
     *
     * @param articleId
     * @return
     *
     * 查询文章详情
     *
     */
    @Override
    public DataMap getArticleByArticleId(long articleId) {

        Article article = articleMapper.getArticleDetailByArticleId(articleId);

        if (article == null) {
            return DataMap.fail(CodeType.ARTICLE_NOT_EXIST);
        }
        //获取文章阅读信息
        String pageName = "article/" + article.getArticleId();

        //获取浏览量
        Object visitorNum = redisTemplate.opsForHash().get("visitor", pageName);
        if (visitorNum == null) {//当redis中没有visitorNum值时
            Visitor visitor = visitorMapper.getVisitorNum(pageName);
            redisTemplate.opsForHash().put("visitor", pageName, visitor.getVisitorNum() + 1);
        } else {
            visitorNum = (int) visitorNum + 1;
            redisTemplate.opsForHash().put("visitor", pageName, visitorNum);
        }

        //获取标签
        String[] tagsList = StringAndArray.stringToArray(article.getArticleTags());

        //获取like信息
        String keyName = String.valueOf(article.getArticleId());
        Object likes = redisTemplate.opsForHash().get("likes", keyName);
        if (likes == null) {//当redis中没有like值时
            likes = statisticMapper.getLikeNum(article.getArticleId());//后期修改为从文章表获取
            redisTemplate.opsForHash().put("likes", keyName, likes);
        }

        JSONObject articleObject = new JSONObject();
        articleObject.put("publishDate", article.getPublishDate());
        articleObject.put("articleTitle", article.getArticleTitle());
        articleObject.put("articleType", article.getArticleType());
        articleObject.put("originalAuthor", article.getOriginalAuthor());
        articleObject.put("articleCategories", article.getArticleCategories());
        articleObject.put("articleContent", article.getArticleContent());
        articleObject.put("articleUrl", article.getArticleUrl());
        articleObject.put("articleTags", tagsList);
        articleObject.put("articleId", article.getArticleId());
        articleObject.put("likes", likes);
        return DataMap.success().setData(articleObject);
    }

    /**
     *
     * 根据目录获得文章
     * @param rows
     * @param pageNum
     * @param category
     * @return
     */
    @Override
    public DataMap getCategoryArticle(Integer rows, Integer pageNum, String category) {
        //数据封装
        HashMap<String, Object> returnHashMap = new HashMap<>();
        PageHelper.startPage(pageNum, rows);

        //获取文章
        List<Article> articleList = articleMapper.getCategoryArticle(category);
        if (articleList == null){//可能存在目录下没有文章的情况
            return DataMap.success(CodeType.ARTICLE_NOT_EXIST);
        }

        //  rows: data['data']['pageInfo']['pageSize'],//每页显示条数
        //                    pageNum: data['data']['pageInfo']['pageNum'],//当前所在页码
        //                    pages: data['data']['pageInfo']['pages'],//总页数
        //                    total: data['data']['pageInfo']['total'],//总记录数
        PageInfo<Article> pageInfo = new PageInfo<>(articleList);
        HashMap<String, Object> pageInfoHashMap = new HashMap<>();
        pageInfoHashMap.put("pageNum", pageInfo.getPageNum());
        pageInfoHashMap.put("pages", pageInfo.getPages());
        pageInfoHashMap.put("total", pageInfo.getTotal());
        pageInfoHashMap.put("pageInfo", pageInfo);
        returnHashMap.put("pageInfo", pageInfoHashMap);

        //data['category']
        returnHashMap.put("category",category);
        //articleId,articleTitle,publishDate,articleCategories,articleTags.length
        //data['result'], function (index, obj)
        ArrayList<HashMap> articleMapList = new ArrayList<>();
        for (Article article : articleList) {
            HashMap<String, Object> object = new HashMap<>();
            object.put("articleId", article.getArticleId());
            object.put("articleTitle", article.getArticleTitle());
            object.put("publishDate", article.getPublishDate());
            object.put("articleCategories", article.getArticleCategories());
            String[] tags = StringAndArray.stringToArray(article.getArticleTags());
            object.put("articleTags", tags);
            articleMapList.add(object);
        }
        returnHashMap.put("result", articleMapList);

        return DataMap.success().setData(returnHashMap);
    }
}
